home *** CD-ROM | disk | FTP | other *** search
- /*
- File: ARPSampleShell.c
-
- Contains: Sample that shows how to talk to the ARP module.
-
- Written by: Quinn "The Eskimo!"
-
- Copyright: Copyright © 1997-1999 by Apple Computer, Inc., All Rights Reserved.
-
- You may incorporate this Apple sample source code into your program(s) without
- restriction. This Apple sample source code has been provided "AS IS" and the
- responsibility for its operation is yours. You are not permitted to redistribute
- this Apple sample source code as "Apple sample source code" after having made
- changes. If you're going to re-distribute the source, we require that you make
- it clear in the source that the code was descended from Apple sample source
- code, but that you've made changes.
-
- Change History (most recent first):
- 7/21/1999 Karl Groethe Updated for Metrowerks Codewarror Pro 2.1
-
-
- */
- ///////////////////////////////////////////////////////////////////
- // Lots of standard OT constructs.
-
- #include <OpenTptClient.h>
- #include <OpenTptInternet.h>
- #include <Memory.h>
-
- ///////////////////////////////////////////////////////////////////
- // This sample makes heavy use of C's standard I/O package.
-
- #include <stdio.h>
-
- ///////////////////////////////////////////////////////////////////
- // Standard C string operations.
-
- #include <string.h>
-
- ///////////////////////////////////////////////////////////////////
- // Constants and types for ARP module messages.
-
- #include "OTARPModule.h"
-
- ///////////////////////////////////////////////////////////////////
- // Prototypes for our high-level interface to ARP.
-
- #include "ARPerations.h"
-
- ///////////////////////////////////////////////////////////////////
-
- // Define a structure for holding a standard hardware address,
- // ie a 6 byte Ethernet address.
-
- struct HardwareAddress {
- UInt8 fHardwareAddress[6];
- };
- typedef struct HardwareAddress HardwareAddress;
-
- ///////////////////////////////////////////////////////////////////
-
- // Define constants for all the default address and such that we
- // assume if you enter a blank field.
-
- static char kDefaultInterfaceName[] = "pci1011,140";
- static HardwareAddress kDefaultHardwareAddress = { 0x00, 0x05, 0x02, 0xBC, 0xC8, 0x4F };
- static InetHost kDefaultIPAddress = ( (17L << 24) || (203L << 16) || (21L << 8) || 98);
- static char kDefaultInterfaceConfig[] = "enet";
-
- ///////////////////////////////////////////////////////////////////
-
- // Routines for reading and writing various address types.
-
- static void GetHardwareAddress(HardwareAddress *hwAddr)
- // Prompt the user for a hardware address.
- {
- unsigned int hw0, hw1, hw2, hw3, hw4, hw5;
- int result;
- char tmpStr[256];
-
- printf("Enter a hardware address:\n");
- tmpStr[0] = 0;
- gets(tmpStr);
- printf("“%s”\n", tmpStr);
- result = sscanf(tmpStr, "%x:%x:%x:%x:%x:%x", &hw0, &hw1, &hw2, &hw3, &hw4, &hw5);
-
- if (result != 6) {
- printf("Wrong answer. Using default hardware address.\n");
- *hwAddr = kDefaultHardwareAddress;
- } else {
- hwAddr->fHardwareAddress[0] = hw0;
- hwAddr->fHardwareAddress[1] = hw1;
- hwAddr->fHardwareAddress[2] = hw2;
- hwAddr->fHardwareAddress[3] = hw3;
- hwAddr->fHardwareAddress[4] = hw4;
- hwAddr->fHardwareAddress[5] = hw5;
- }
- }
-
- static void HardwareAddressToString(HardwareAddress hwAddr, char *outputString)
- // Convert a hardware address to a string suitable for printing.
- {
- sprintf(outputString, "%02x:%02x:%02x:%02x:%02x:%02x",
- hwAddr.fHardwareAddress[0],
- hwAddr.fHardwareAddress[1],
- hwAddr.fHardwareAddress[2],
- hwAddr.fHardwareAddress[3],
- hwAddr.fHardwareAddress[4],
- hwAddr.fHardwareAddress[5]
- );
- }
-
- static void GetInterfaceName(char *intfName)
- // Prompt the user for an interface name.
- {
- printf("Enter an ARP interface name (press return for “%s”):\n", kDefaultInterfaceName);
- intfName[0] = 0;
- gets(intfName);
- if (intfName[0] == 0) {
- strcpy(intfName, kDefaultInterfaceName);
- }
- }
-
- static void GetIPAddress(InetHost *ipAddr)
- // Prompt the user for an IP address.
- {
- char tmpStr[256];
- unsigned int ip0, ip1, ip2, ip3;
- int result;
-
- printf("Enter an IP address:\n");
- tmpStr[0] = 0;
- gets(tmpStr);
- result = sscanf(tmpStr, "%d.%d.%d.%d", &ip0, &ip1, &ip2, &ip3);
-
- if (result != 4) {
- printf("Wrong answer. Using default IP address.\n");
- *ipAddr = kDefaultIPAddress;
- } else {
- *ipAddr = (ip0 << 24) | (ip1 << 16) | (ip2 << 8) | ip3;
- }
- }
-
- static void IPAddressToString(InetHost ipAddr, char *outputString)
- // Convert an IP address to a string suitable for printing.
- {
- sprintf(outputString, "%d.%d.%d.%d",
- (ipAddr >> 24) & 0x0ff,
- (ipAddr >> 16) & 0x0ff,
- (ipAddr >> 8) & 0x0ff,
- (ipAddr >> 0) & 0x0ff
- );
- }
-
- static void GetFlag(char *flagName, UInt32 flagValue, UInt32 *flags)
- // Prompt the user for a flag. The flagName is the user-visible
- // name of the flag. If the user types anything other than
- // return or "n", flagVlaue is ORed into the flags variable.
- {
- char tmpStr[256];
-
- printf("%s? (y/n)\n", flagName);
- gets(tmpStr);
- if ( tmpStr[0] != 0 && tmpStr[0] != 'n' && tmpStr[0] != 'N') {
- (*flags) |= flagValue;
- }
- }
-
- static void PrintFlag(char *flagName, UInt32 flagMask, UInt32 flags)
- // Print a flag.
- {
- if ( (flags & flagMask) != 0 ) {
- printf("%s ", flagName);
- }
- }
-
- ///////////////////////////////////////////////////////////////////
-
- static OSStatus DoARPGetCacheReport(void)
- // Call through to the equivalent ARPerations routine
- // and then print the results.
- {
- OSStatus err;
- Handle cacheReportHandle;
- char zero;
-
- printf("DoARPGetCacheReport\n");
- cacheReportHandle = NewHandle(0);
- err = MemError();
- if (err == noErr) {
- err = ARPGetCacheReport(cacheReportHandle);
- if (err == noErr) {
- zero = 0;
- err = PtrAndHand(&zero, cacheReportHandle, sizeof(zero));
- if (err == noErr) {
- HLock(cacheReportHandle);
- printf("%s\n\n", *cacheReportHandle);
- }
- }
- DisposeHandle(cacheReportHandle);
- }
- printf("\n");
- return (err);
- }
-
- ///////////////////////////////////////////////////////////////////
-
- static OSStatus DoARPAddEntry(void)
- // Prompt user for input and then call straight through
- // to the equivalent ARPerations routine.
- {
- OSStatus err;
- char interfaceName[256];
- InetHost ipAddr;
- InetHost ipMask = 0xFFFFFFFF;
- HardwareAddress hwAddr;
- char ipAddrString[256];
- char hwAddrString[256];
- UInt32 flags;
-
- printf("DoARPAddEntry\n");
- GetInterfaceName(interfaceName);
- GetIPAddress(&ipAddr);
- IPAddressToString(ipAddr, ipAddrString);
- GetHardwareAddress(&hwAddr);
- HardwareAddressToString(hwAddr, hwAddrString);
- flags = 0;
- GetFlag("PERM ", ACE_F_PERMANENT, &flags);
- GetFlag("PUBLISH", ACE_F_PUBLISH, &flags);
- GetFlag("MAPPING", ACE_F_MAPPING, &flags);
-
- printf("Adding ARP cache entry for %s -> %s on “%s”.\n", ipAddrString, hwAddrString, interfaceName);
-
- err = ARPAddEntry(interfaceName, IP_ARP_PROTO_TYPE, flags,
- &ipAddr, sizeof(InetHost), &ipMask, &hwAddr, sizeof(hwAddr));
-
- return (err);
- }
-
- ///////////////////////////////////////////////////////////////////
-
- static OSStatus DoARPDeleteEntry(void)
- // Prompt user for input and then call straight through
- // to the equivalent ARPerations routine.
- {
- OSStatus err;
- InetHost ipAddr;
- char interfaceName[256];
- char ipAddrString[256];
-
- printf("DoARPDeleteEntry\n");
- GetInterfaceName(interfaceName);
- GetIPAddress(&ipAddr);
- IPAddressToString(ipAddr, ipAddrString);
-
- printf("Deleting ARP cache entry for %s on “%s”.\n", ipAddrString, interfaceName);
-
- err = ARPDeleteEntry(interfaceName, IP_ARP_PROTO_TYPE, &ipAddr, sizeof(InetHost));
-
- return (err);
- }
-
- ///////////////////////////////////////////////////////////////////
-
- static OSStatus DoARPCacheQuery(void)
- // Prompt user for input, call through to the equivalent
- // ARPerations routine, and then print the results.
- {
- OSStatus err;
- char interfaceName[256];
- InetHost ipAddr;
- HardwareAddress hwAddr;
- char ipAddrString[256];
- char hwAddrString[256];
- UInt32 flags;
-
- printf("DoARPCacheQuery\n");
- GetInterfaceName(interfaceName);
- GetIPAddress(&ipAddr);
- IPAddressToString(ipAddr, ipAddrString);
-
- printf("Lookup ARP cache entry for %s on “%s”.\n", ipAddrString, interfaceName);
-
- err = ARPCacheQuery(interfaceName,
- IP_ARP_PROTO_TYPE,
- &ipAddr, sizeof(InetHost),
- &hwAddr, sizeof(hwAddr), &flags);
-
- if (err == noErr) {
- HardwareAddressToString(hwAddr, hwAddrString);
- printf("Hardware address is %s.\n", hwAddrString);
- printf("Flags are ");
- PrintFlag("PERM", ACE_F_PERMANENT, flags);
- PrintFlag("PUBLISH", ACE_F_PUBLISH, flags);
- PrintFlag("DYING", ACE_F_DYING, flags);
- PrintFlag("RESOLVED", ACE_F_RESOLVED, flags);
- PrintFlag("MAPPING", ACE_F_MAPPING, flags);
- printf("\n");
- }
-
- return (err);
- }
-
- ///////////////////////////////////////////////////////////////////
-
- // This sample uses a big global array (gInterfacesWeBroughtUp) to store
- // the list of interfaces that we have brought up. The top of this
- // array is defined by gMaxInterfaceIndex. The array stores
- // the configuration string used to create the interface (so that
- // we can display it to the user) and the interfaceCookie returned
- // by ARPInterfaceUp (so we can pass it back to ARPInterfaceDown
- // to tear down the interface).
-
- enum {
- kNumberOfOurARPInterfaces = 10 // Obviously an arbitrary limit.
- };
-
- struct InterfaceInfo {
- UInt32 cookie;
- char configString[256];
- };
- typedef struct InterfaceInfo InterfaceInfo;
-
- static InterfaceInfo gInterfacesWeBroughtUp[kNumberOfOurARPInterfaces];
-
- static SInt32 gMaxInterfaceIndex = -1;
-
- static OSStatus DoARPPrintOurInterfaces(void)
- // Print the list of ARP interfaces we have brought up.
- {
- SInt32 interfaceIndex;
-
- printf("DoARPPrintOurInterfaces\n");
- printf("Interfaces we brought up:\n");
- for (interfaceIndex = 0; interfaceIndex <= gMaxInterfaceIndex; interfaceIndex++) {
- printf("%2d -- %s\n",
- interfaceIndex,
- gInterfacesWeBroughtUp[interfaceIndex].configString
- );
- }
- printf("\n");
- return (noErr);
- }
-
- static OSStatus DoARPInterfaceUp(void)
- // Prompt user for input and then call through to ARPInterfaceUp
- // to bring up the interface. If this succeeds, record the
- // interface in gInterfacesWeBroughtUp so we can tear it down
- // again.
- {
- OSStatus err;
-
- printf("DoARPInterfaceUp\n");
- err = noErr;
- if ( gMaxInterfaceIndex == (kNumberOfOurARPInterfaces - 1) ) {
- err = -3;
- }
- if (err == noErr) {
- printf("Enter the configuration string of the interface you want to bring up:\n");
- gInterfacesWeBroughtUp[gMaxInterfaceIndex + 1].configString[0] = 0;
- gets(gInterfacesWeBroughtUp[gMaxInterfaceIndex + 1].configString);
- if ( gInterfacesWeBroughtUp[gMaxInterfaceIndex + 1].configString[0] == 0 ) {
- OTStrCopy(gInterfacesWeBroughtUp[gMaxInterfaceIndex + 1].configString, kDefaultInterfaceConfig);
- }
- }
- if (err == noErr) {
- err = ARPInterfaceUp(gInterfacesWeBroughtUp[gMaxInterfaceIndex + 1].configString,
- &gInterfacesWeBroughtUp[gMaxInterfaceIndex + 1].cookie);
- }
- if (err == noErr) {
- gMaxInterfaceIndex += 1;
- }
-
- return (err);
- }
-
- static OSStatus DoARPInterfaceDown(void)
- // Prompt user for the numeric index of the interface they
- // want to tear down, and then call through to ARPInterfaceDown
- // to tear it down. Afterwards, delete the torn down element from
- // the gInterfacesWeBroughtUp array
- {
- OSStatus err;
- SInt32 interfaceIndex;
- char tmpStr[256];
-
- printf("DoARPInterfaceDown\n");
- (void) DoARPPrintOurInterfaces();
- printf("Enter an interface to take down:\n");
- tmpStr[0] = 0;
- gets(tmpStr);
- err = noErr;
- if ( sscanf(tmpStr, "%ld", &interfaceIndex) != 1 ) {
- err = -1;
- }
- if (err == noErr) {
- if ( (interfaceIndex < 0) || (interfaceIndex > gMaxInterfaceIndex) ) {
- err = -2;
- }
- }
- if (err == noErr) {
- err = ARPInterfaceDown(gInterfacesWeBroughtUp[interfaceIndex].cookie);
- }
- if (err == noErr) {
- gInterfacesWeBroughtUp[interfaceIndex] = gInterfacesWeBroughtUp[gMaxInterfaceIndex];
- gMaxInterfaceIndex -= 1;
- }
-
- return (err);
- }
-
- ///////////////////////////////////////////////////////////////////
-
- static OSStatus DoPrintCommandHelp(void)
- // Print the current list of commands.
- {
- printf("DoPrintCommandHelp\n");
- printf("?) Prints this help.\n");
- printf("\n");
- printf("p) Print contents of ARP cache.\n");
- printf("a) Add an ARP cache entry.\n");
- printf("k) Delete an ARP cache entry.\n");
- printf("l) Lookup an ARP cache entry.\n");
- printf("\n");
- printf("i) See the ARP interfaces we have brought up.\n");
- printf("u) Bring up a new ARP interface.\n");
- printf("d) Tear down an ARP interface.\n");
- printf("\n");
- printf("q) Quit.\n");
-
- return (noErr);
- }
-
- ///////////////////////////////////////////////////////////////////
-
- void main(void)
- {
- OSStatus err;
- char commandStr[256];
- Boolean quitNow;
-
- printf("ARPSample -- A poor man's ARPing tool.\n");
-
- err = InitOpenTransport();
-
- if (err == noErr) {
-
- quitNow = false;
- (void) DoPrintCommandHelp();
-
- // Welcome to the command loop. Get a string from the user
- // and use the first letter to dispatch to the relevant
- // subroutine.
-
- do {
- printf("Enter a letter corresponding to a command.\n");
-
- err = noErr;
- gets(commandStr);
- switch (commandStr[0]) {
- case '?':
- err = DoPrintCommandHelp();
- break;
- case 'p':
- err = DoARPGetCacheReport();
- break;
- case 'a':
- err = DoARPAddEntry();
- break;
- case 'k':
- err = DoARPDeleteEntry();
- break;
- case 'l':
- err = DoARPCacheQuery();
- break;
- case 'i':
- err = DoARPPrintOurInterfaces();
- break;
- case 'u':
- err = DoARPInterfaceUp();
- break;
- case 'd':
- err = DoARPInterfaceDown();
- break;
- case 'q':
- quitNow = true;
- break;
- case '\n':
- break;
- default:
- printf("Huh? “%s”\n", commandStr);
- break;
- }
- if (err != noErr) {
- printf("Error %ld.\n", err);
- }
- } while ( ! quitNow );
-
- CloseOpenTransport();
- }
-
- if (err == noErr) {
- printf("Success.\n");
- } else {
- printf("Failed with error %d.\n", err);
- }
- printf("Done. Press command-Q to Quit.\n");
- }
-
-